<?php

class HasManyAssociationDAO extends AssociationDAO
{

  /**
   * (non-PHPdoc)
   * @see simplify/kernel/domain/association/AssociationDAO#afterSave($client)
   */
  public function afterSave(&$client, $dao, $params = array())
  {
    $name = $this->getDefinition()->getName();

    if (isset($client[$name])) {
      $pk = $this->getDefinition()->getPrimaryKeyField()->getName();

      if (! isset($client[$pk])) {
        throw new Exception('Cannot save associated data: primary key of source object not set');
      }

      $fk = $this->getDefinition()->getForeignKeyField()->getName();

      $_client = array(
        $pk => $client[$pk]
      );

      $this->find($_client);

      $diff = sy_data_diff($_client[$name], $client[$name], $this->getDefinition()->getTarget()->getPkName());

      //$dao = RepositoryDAO::getInstance($this->getDefinition()->getTarget()->getName());
      //$dao = CustomRepository::getInstance($this->getDefinition()->getTarget()->getName());

      foreach ($diff['delete'] as $row) {
        $dao->delete($row, $params);
      }

      $client[$name] = array_merge($diff['create'], $diff['update']);

      foreach ($client[$name] as &$data) {
        $data[$fk] = $client[$pk];
        //$dao->save($data, $params);
        $dao->_save($data, $this->getDefinition()->getTarget(), $params);
      }
    }
  }

  /**
   * (non-PHPdoc)
   * @see simplify/kernel/domain/association/AssociationDAO#find($clients)
   */
  public function find(&$clients, $params = null)
  {
    $dao = DAO::getInstance();

    $name = $this->getDefinition()->getName();

    $table = $this->getDefinition()->getTarget()->getTable();
    $fk = $this->getDefinition()->getForeignKeyField()->getName();
    $pk = $this->getDefinition()->getPrimaryKeyField()->getName();
    $fields = RepositoryDAO::collectFields($this->getDefinition()->getTarget());

    $query = $dao->query();

    $params = (array)$params;
    if (isset($params['where'])) {
      $query->where($params['where']);
    }

    if (isset($clients[$pk])) {
      $id = $clients[$pk];

      $query->from($table)->select($fields)->where("$fk = ?");
      $result = $query->execute($id);

      $data = $result->fetchAll();

      $clients[$name] = $data;
    }
    else {
      $ids = array();
      foreach ($clients as $client) {
        $ids[] = $client[$pk];
      }

      if (! empty($ids)) {
        $ids = array_unique($ids);
        $ids = implode(', ', $ids);

        $query->from($table)->select($fields)->where("$fk IN ($ids)");
        $result = $query->execute();

        $data = $result->fetchAll();

        $_data = array();
        foreach ($data as $row) {
          if (! isset($_data[$row[$fk]])) {
            $_data[$row[$fk]] = array();
          }

          $_data[$row[$fk]][] = $row;
        }

        $data = $_data;
      }

      foreach ($clients as & $client) {
        if (isset($data[$client[$pk]])) {
          $client[$name] = $data[$client[$pk]];
        }
        elseif ($this->getDefinition()->isRequired()) {
          $client[$name] = array();
        }
      }
    }
  }

}

?>